package edu.hubu.store.controller;

import edu.hubu.store.domain.Notice;
import edu.hubu.store.domain.PageBean;
import edu.hubu.store.domain.Product;
import edu.hubu.store.domain.User;
import edu.hubu.store.domain.*;
import edu.hubu.store.exception.AddProductException;
import edu.hubu.store.exception.FindProductByIdException;
import edu.hubu.store.exception.ListProductException;
import edu.hubu.store.exception.RegisterException;
import edu.hubu.store.service.NoticeService;
import edu.hubu.store.service.OrderService;
import edu.hubu.store.service.ProductService;
import edu.hubu.store.service.UserService;
import edu.hubu.store.utils.ActiveCodeUtils;
import edu.hubu.store.utils.FileUploadUtils;
import edu.hubu.store.utils.IdUtils;
import edu.hubu.store.utils.PaymentUtil;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.io.IOUtils;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.imageio.ImageIO;
import javax.security.auth.login.LoginException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;

/**
 * @author waxijiang
 */
@Controller
@RequestMapping("/")
public class ClientController {
    @Autowired
    NoticeService nService;


    @Autowired
    UserService userService;

    @Autowired
    ProductService productService;

    private Color getRandColor(int fc, int bc) {
        // 取其随机颜色
        Random random = new Random();
        if (fc > 255) {
            fc = 255;
        }
        if (bc > 255) {
            bc = 255;
        }
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }
    private List<String> words = new ArrayList<String>();
    @RequestMapping("/imageCode")
    public void checkImage(HttpServletRequest request, HttpServletResponse response) {
        // 初始化阶段，读取new_words.txt
        // web工程中读取文件，必须使用绝对磁盘路径
        String path = request.getServletContext().getRealPath("/WEB-INF/new_words.txt");
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    new FileInputStream(path), "utf-8"));
            String line;
            while ((line = reader.readLine()) != null) {
                words.add(line);
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 禁止缓存
        // response.setHeader("Cache-Control", "no-cache");
        // response.setHeader("Pragma", "no-cache");
        // response.setDateHeader("Expires", -1);
        int width = 180;
        int height = 30;
        // 步骤一 绘制一张内存中图片
        BufferedImage bufferedImage = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);
        // 步骤二 图片绘制背景颜色 ---通过绘图对象
        Graphics graphics = bufferedImage.getGraphics();// 得到画图对象 --- 画笔
        // 绘制任何图形之前 都必须指定一个颜色
        graphics.setColor(getRandColor(200, 250));
        graphics.fillRect(0, 0, width, height);
        // 步骤三 绘制边框
        graphics.setColor(Color.WHITE);
        graphics.drawRect(0, 0, width - 1, height - 1);
        // 步骤四 四个随机数字
        Graphics2D graphics2d = (Graphics2D) graphics;
        // 设置输出字体
        graphics2d.setFont(new Font("宋体", Font.BOLD, 18));
        Random random = new Random();// 生成随机数
        int index = random.nextInt(words.size());
        String word = words.get(index-1);// 获得成语
        // 定义x坐标
        int x = 10;
        for (int i = 0; i < word.length(); i++) {
            // 随机颜色
            graphics2d.setColor(new Color(20 + random.nextInt(110), 20 + random
                    .nextInt(110), 20 + random.nextInt(110)));
            // 旋转 -30 --- 30度
            int jiaodu = random.nextInt(60) - 30;
            // 换算弧度
            double theta = jiaodu * Math.PI / 180;
            // 获得字母数字
            char c = word.charAt(i);
            // 将c 输出到图片
            graphics2d.rotate(theta, x, 20);
            graphics2d.drawString(String.valueOf(c), x, 20);
            graphics2d.rotate(-theta, x, 20);
            x += 40;
        }
        // 将验证码内容保存session
        request.getSession().setAttribute("checkcode_session", word);
        // 步骤五 绘制干扰线
        graphics.setColor(getRandColor(160, 200));
        int x1;
        int x2;
        int y1;
        int y2;
        for (int i = 0; i < 30; i++) {
            x1 = random.nextInt(width);
            x2 = random.nextInt(12);
            y1 = random.nextInt(height);
            y2 = random.nextInt(12);
            graphics.drawLine(x1, y1, x1 + x2, x2 + y2);
        }
        // 将上面图片输出到浏览器 ImageIO
        graphics.dispose();// 释放资源
        try {
            ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 登录
     * @param request
     * @param response
     * @return
     */
    @PostMapping("login")
    public String login(HttpServletRequest request, HttpServletResponse response) {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        // 2.调用service完成登录操作。
        try {
            User user = userService.login(username, password);

            // 3.登录成功，将用户存储到session中.
            request.getSession().setAttribute("user", user);
            // 获取用户的角色，其中用户的角色分普通用户和超级用户两种
            String role = user.getRole(); 
            // 如果是超级用户，就进入到网上书城的后台管理系统；否则进入我的账户页面
            if ("超级用户".equals(role)) {
                return "redirect:admin/login/home.jsp";
            } else {
                return "redirect:/client/myAccount.jsp";
            }
        } catch (LoginException e) {
            // 如果出现问题，将错误信息存储到request范围，并跳转回登录页面显示错误信息
            e.printStackTrace();
            request.setAttribute("register_message", e.getMessage());
            return "forward:/client/login.jsp";
        }
    }

    @RequestMapping("/addProduct")
    public String addProduct(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 创建javaBean,将上传数据封装.
        Product p = new Product();
        String name = request.getParameter("name");
        String price = request.getParameter("price");
        String pnum = request.getParameter("pnum");
        String category = request.getParameter("category");
        String description = request.getParameter("description");
        p.setDescription(description);
        p.setCategory(category);
        p.setName(name);
        p.setPnum(Integer.parseInt(pnum));
        p.setPrice(Double.parseDouble(price));
        Map<String, String> map = new HashMap<String, String>();
        // 封装商品id
        map.put("id", IdUtils.getUUID());

        DiskFileItemFactory dfif = new DiskFileItemFactory();
        // 设置临时文件存储位置
        dfif.setRepository(new File(request.getServletContext().getRealPath("/temp")));
        // 设置上传文件缓存大小为10m
        dfif.setSizeThreshold(1024 * 1024 * 10);
        // 创建上传组件
        ServletFileUpload upload = new ServletFileUpload(dfif);
        // 处理上传文件中文乱码
        upload.setHeaderEncoding("utf-8");
        try {
            // 解析request得到所有的FileItem
            List<FileItem> items = upload.parseRequest(request);
            // 遍历所有FileItem
            for (FileItem item : items) {
                // 判断当前是否是上传组件
                if (item.isFormField()) {
                    // 不是上传组件
                    String fieldName = item.getFieldName(); // 获取组件名称
                    String value = item.getString("utf-8"); // 解决乱码问题
                    map.put(fieldName, value);
                } else {
                    // 是上传组件
                    // 得到上传文件真实名称
                    String fileName = item.getName();
                    fileName = FileUploadUtils.subFileName(fileName);

                    // 得到随机名称
                    String randomName = FileUploadUtils.generateRandonFileName(fileName);

                    // 得到随机目录
                    String randomDir = FileUploadUtils.generateRandomDir(randomName);
                    // 图片存储父目录
                    String imgurl_parent = "/productImg" + randomDir;

                    File parentDir = new File(request.getServletContext().getRealPath(imgurl_parent));
                    // 验证目录是否存在，如果不存在，创建出来
                    if (!parentDir.exists()) {
                        parentDir.mkdirs();
                    }
                    String imgurl = imgurl_parent + "/" + randomName;

                    map.put("imgurl", imgurl);

                    IOUtils.copy(item.getInputStream(), new FileOutputStream(new File(parentDir, randomName)));
                    item.delete();
                }
            }
        } catch (FileUploadException | UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            // 将数据封装到javaBean中
            BeanUtils.populate(p, map);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        try {
            // 调用service完成添加商品操作
            productService.addProduct(p);
            return "redirect:/listProduct";
        } catch (AddProductException e) {
            e.printStackTrace();
            response.getWriter().write("添加商品失败");
            // TODO: 2020/12/17   无可用跳转页面
            return "redirect:error";
        }
    }

    @RequestMapping("/")
    public String showIndex(HttpServletRequest req, HttpServletResponse resp) {
        //查询最近一条公告，传递到index.jsp页面进行展示
        Notice notice = nService.getRecentNotice();
        req.setAttribute("n", notice);

        //查询本周热销的两条商品，传递到index.jsp页面进行展示
        List<Object[]> pList = pService.getWeekHotProduct();
		/*for(Object[] os:pList){
			for(Object o:os){
				System.out.println(o);
			}
			System.out.println("---------------------");
		}*/
        req.setAttribute("pList", pList);

        return "forward:/client/index.jsp";
    }

    @RequestMapping("logout")
    public void logout(HttpServletRequest request, HttpServletResponse response) {
        // 获取session对象.
        HttpSession session = request.getSession();
        // 销毁session
        session.invalidate();
        // flag标识
        String flag = request.getParameter("flag");
        if (flag == null || flag.trim().isEmpty()) {
            // 重定向到首页
            try {
                response.sendRedirect(request.getContextPath() + "/index.jsp");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @RequestMapping("MenuSearchServlet")
    public void menuSearch(HttpServletRequest req, HttpServletResponse resp) {
        // 1.定义当前页码，默认为1
        int currentPage = 1;
        String _currentPage = req.getParameter("currentPage");
        if (_currentPage != null) {
            currentPage = Integer.parseInt(_currentPage);
        }
        // 2.定义每页显示条数,默认为4
        int currentCount = 4;
        //获取前台页面搜索框输入的值
        String searchfield = req.getParameter("textfield");
        //如果搜索框中没有输入值，则表单传递的为默认值，此时默认查询全部商品目录
        if ("请输入书名".equals(searchfield)) {
            try {
                req.getRequestDispatcher("/showProductByPage").forward(req, resp);
            } catch (ServletException | IOException e) {
                e.printStackTrace();
            }
            return;
        }
        //调用service层的方法，通过书名模糊查询，查找相应的图书
        PageBean bean = productService.findBookByName(currentPage, currentCount, searchfield);
        // 将数据存储到request范围，跳转到product_search_list.jsp页面展示
        req.setAttribute("bean", bean);
        try {
            req.getRequestDispatcher("/client/product_search_list.jsp").forward(req, resp);
        } catch (ServletException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @RequestMapping("myAccount")
    public void myAccount(HttpServletRequest request, HttpServletResponse response) {
        /**
         * 点击前台系统中的【我的账户】，分以下两种情况：
         * 1、用户未登录，进入登录页面
         * 2、用户已登录
         *   a、超级用户，进入到后台系统
         *   b、普通用户，登录到我的账户
         */
        //在session中查找名为“user”的会话
        User user = (User) request.getSession().getAttribute("user");
        //如果找到没有名为“user”的会话，说明用户没有登录，此时跳转到登录页面
        if (user == null) {
            try {
                response.sendRedirect(request.getContextPath() + "/client/login.jsp");
            } catch (IOException e) {
                e.printStackTrace();
            }
            return;
        }
        //如果是超级用户，进入到网上书城后台管理系统；否则进入到普通用户的账户信息页面
        if ("超级用户".equals(user.getRole())) {
            try {
                response.sendRedirect(request.getContextPath() + "/admin/login/home.jsp");
            } catch (IOException e) {
                e.printStackTrace();
            }
            //			return;
        } else {
            try {
                response.sendRedirect(request.getContextPath() + "/client/myAccount.jsp");
            } catch (IOException e) {
                e.printStackTrace();
            }
            //			return;
        }
    }

/*    @RequestMapping("onlinepay")
    public void onlinePay(HttpServletRequest request, HttpServletResponse response) {
        // 1.将要提交的数据得到
        // 获得 支付必须基本数据
        String orderid = request.getParameter("orderid");
        String money = request.getParameter("money");
        // 银行
        String pd_FrpId = request.getParameter("yh");

        // 发给支付公司需要哪些数据
        String p0_Cmd = "Buy";
        String p1_MerId = ResourceBundle.getBundle("merchantInfo").getString("p1_MerId");
        String p2_Order = orderid;
        String p3_Amt = money;
        String p4_Cur = "CNY";
        String p5_Pid = "";
        String p6_Pcat = "";
        String p7_Pdesc = "";
        // 支付成功回调地址 ---- 第三方支付公司会访问、用户访问
        // 第三方支付可以访问网址
        String p8_Url = ResourceBundle.getBundle("merchantInfo").getString("responseURL");
        String p9_SAF = "";
        String pa_MP = "";
        String pr_NeedResponse = "1";

        // 加密hmac 需要密钥
        String keyValue = ResourceBundle.getBundle("merchantInfo").getString("keyValue");
        String hmac = PaymentUtil.buildHmac(p0_Cmd, p1_MerId, p2_Order, p3_Amt, p4_Cur, p5_Pid, p6_Pcat, p7_Pdesc, p8_Url, p9_SAF, pa_MP, pd_FrpId, pr_NeedResponse, keyValue);

        // 2.将数据提交到指定的路径

        // response.sendRedirect("https://www.yeepay.com/app-merchant-proxy/node?p0_Cmd="+p0_Cmd+"&p1_MerId="+p1_MerId);

        request.setAttribute("pd_FrpId", pd_FrpId);
        request.setAttribute("p0_Cmd", p0_Cmd);
        request.setAttribute("p1_MerId", p1_MerId);
        request.setAttribute("p2_Order", p2_Order);
        request.setAttribute("p3_Amt", p3_Amt);
        request.setAttribute("p4_Cur", p4_Cur);
        request.setAttribute("p5_Pid", p5_Pid);
        request.setAttribute("p6_Pcat", p6_Pcat);
        request.setAttribute("p7_Pdesc", p7_Pdesc);
        request.setAttribute("p8_Url", p8_Url);
        request.setAttribute("p9_SAF", p9_SAF);
        request.setAttribute("pa_MP", pa_MP);
        request.setAttribute("pr_NeedResponse", pr_NeedResponse);
        request.setAttribute("hmac", hmac);

        try {
            request.getRequestDispatcher("/client/confirm.jsp").forward(request, response);
        } catch (ServletException | IOException e) {
            e.printStackTrace();
        }
    }*/

/*    @RequestMapping("pay")
    public void pay(HttpServletRequest request, HttpServletResponse response) {
        // 1.将要提交的数据得到
        // 获得 支付必须基本数据
        String orderid = request.getParameter("orderid");
        String money = request.getParameter("money");
        // 银行
        String bank = request.getParameter("yh");
        request.setAttribute("bank", bank);
        request.setAttribute("orderid", orderid);
        request.setAttribute("money", money);
        try {
            request.getRequestDispatcher("/client/confirm.jsp").forward(request, response);
        } catch (ServletException | IOException e) {
            e.printStackTrace();
        }
    }*/

    @RequestMapping("register")
    public void register(HttpServletRequest request, HttpServletResponse response) {
        // 将表单提交的数据封装到javaBean
        User user = new User();
        try {
            BeanUtils.populate(user, request.getParameterMap());
            // 封裝激活码
            user.setActiveCode(ActiveCodeUtils.createActiveCode());
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        // 调用service完成注册操作。
        try {
            userService.register(user);
        } catch (RegisterException e) {
            e.printStackTrace();
            try {
                response.getWriter().write(e.getMessage());
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
            return;
        }
        // 注册成功，跳转到registersuccess.jsp
        try {
            response.sendRedirect(request.getContextPath() + "/client/registersuccess.jsp");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("ShowIndexServlet")
    public void showIndexServlet(HttpServletRequest req, HttpServletResponse resp) {
        //查询最近一条公告，传递到index.jsp页面进行展示
        Notice notice = nService.getRecentNotice();
        req.setAttribute("n", notice);

        //查询本周热销的两条商品，传递到index.jsp页面进行展示
        //        List<Object[]> pList = pService.getWeekHotProduct();

        //        req.setAttribute("pList", pList);

        //请求转发
        try {
            req.getRequestDispatcher("/client/index.jsp").forward(req, resp);
        } catch (ServletException | IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("showProductByPage")
    public void showProductByPageServlet(HttpServletRequest request, HttpServletResponse response) {
        // 1.定义当前页码，默认为1
        int currentPage = 1;
        String _currentPage = request.getParameter("currentPage");
        if (_currentPage != null) {
            currentPage = Integer.parseInt(_currentPage);
        }
        // 2.定义每页显示条数,默认为4
        int currentCount = 4;
        String _currentCount = request.getParameter("currentCount");
        if (_currentCount != null) {
            currentCount = Integer.parseInt(_currentCount);
        }
        // 3.获取查找的分类
        String category = null;
        String _category = request.getParameter("category");
        if (!"".equals(_category)) {
            category = _category;
        }
        // 4.调用service，完成获取当前页分页Bean数据.
        PageBean bean = productService.findProductByPage(currentPage, currentCount, category);
        // 将数据存储到request范围，跳转到product_list.jsp页面展示
        request.setAttribute("bean", bean);
        try {
            request.getRequestDispatcher("/client/product_list.jsp").forward(request, response);
        } catch (ServletException | IOException e) {
            e.printStackTrace();
        }
    }


    /*@RequestMapping("/activeUser")
    public void activeUser(HttpServletRequest request, HttpServletResponse response) {
        // 1.获取激活码
        String activeCode = request.getParameter("activeCode");
        // 2.调用service中激活用户操作
        try {
            userService.activeUser(activeCode);
            response.sendRedirect(request.getContextPath() + "/client/activesuccess.jsp");
        } catch (Exception e) {
            e.printStackTrace();
            try {
                response.getWriter().write(e.getMessage());
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        }
    }*/

    @RequestMapping("/addCart")
    public void addCart(HttpServletRequest request, HttpServletResponse response) {
        // 1.得到商品id
        String id = request.getParameter("id");
        // 2.调用service层方法，根据id查找商品
        try {
            Product p = productService.findProductById(id);
            //3.将商品添加到购物车
            //3.1获得session对象
            HttpSession session = request.getSession();
            //3.2从session中获取购物车对象
            Map<Product, Integer> cart = (Map<Product, Integer>) session.getAttribute("cart");
            //3.3如果购物车为null,说明没有商品存储在购物车中，创建出购物车
            if (cart == null) {
                cart = new HashMap<Product, Integer>();
            }
            //3.4向购物车中添加商品
            Integer count = cart.put(p, 1);
            //3.5如果商品数量不为空，则商品数量+1，否则添加新的商品信息
            if (count != null) {
                cart.put(p, count + 1);
            }
            session.setAttribute("cart", cart);
            response.sendRedirect(request.getContextPath() + "/client/cart.jsp");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Autowired
    OrderService orderService;

/*    @RequestMapping("/callback")
    public void callBack(HttpServletRequest request, HttpServletResponse response) {
        // 获得回调所有数据
        String p1_MerId = request.getParameter("p1_MerId");
        String r0_Cmd = request.getParameter("r0_Cmd");
        String r1_Code = request.getParameter("r1_Code");
        String r2_TrxId = request.getParameter("r2_TrxId");
        String r3_Amt = request.getParameter("r3_Amt");
        String r4_Cur = request.getParameter("r4_Cur");
        String r5_Pid = request.getParameter("r5_Pid");
        String r6_Order = request.getParameter("r6_Order");
        String r7_Uid = request.getParameter("r7_Uid");
        String r8_MP = request.getParameter("r8_MP");
        String r9_BType = request.getParameter("r9_BType");
        String rb_BankId = request.getParameter("rb_BankId");
        String ro_BankOrderId = request.getParameter("ro_BankOrderId");
        String rp_PayDate = request.getParameter("rp_PayDate");
        String rq_CardNo = request.getParameter("rq_CardNo");
        String ru_Trxtime = request.getParameter("ru_Trxtime");
        // 身份校验 --- 判断是不是支付公司通知你
        String hmac = request.getParameter("hmac");
        String keyValue = ResourceBundle.getBundle("merchantInfo").getString("keyValue");

        // 自己对上面数据进行加密 --- 比较支付公司发过来hamc
        boolean isValid = PaymentUtil.verifyCallback(hmac, p1_MerId, r0_Cmd, r1_Code, r2_TrxId, r3_Amt, r4_Cur, r5_Pid, r6_Order, r7_Uid, r8_MP, r9_BType, keyValue);
        if (isValid) {

            if ("1".equals(r9_BType) || "2".equals(r9_BType)) { // 判断正确支付.
                // 响应数据有效--完成修改订单状态操作
                try {
                    response.getWriter().print("success");
                } catch (IOException e) {
                    e.printStackTrace();
                }

                // 根据订单号修改订单状态
                try {
                    orderService.updateState(r6_Order);
                } catch (Exception e) {
                    e.printStackTrace();
                    try {
                        response.getWriter().write("修改订单状态失败");
                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                    }
                }
            }

        } else {
            // 数据无效
            try {
                response.getWriter().write("数据被篡改！");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }*/

    @RequestMapping("/changeCart")
    public void changeCart(HttpServletRequest request, HttpServletResponse response) {
        // 1.得到商品id
        String id = request.getParameter("id");
        // 2.得到要修改的数量
        int count = Integer.parseInt(request.getParameter("count"));
        // 3.从session中获取购物车.
        HttpSession session = request.getSession();
        Map<Product, Integer> cart = (Map<Product, Integer>) session.getAttribute("cart");
        Product p = new Product();
        p.setId(id);
        if (count != 0) {
            cart.put(p, count);
        } else {
            cart.remove(p);
        }
        try {
            response.sendRedirect(request.getContextPath() + "/client/cart.jsp");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Autowired
    ProductService pService;
    @RequestMapping("/orderstate")
    public void changeOrderState(HttpServletRequest request, HttpServletResponse response) {
        // 获得订单号数据
        String orderid = request.getParameter("orderid");
        String paySuccess = "恭喜您支付成功！";
        if (null != orderid) {
            // 根据订单号修改订单状态
            try {
                orderService.updateState(orderid);
                request.setAttribute("paySuccess", paySuccess);
                request.getRequestDispatcher("/findOrderByUser").forward(request, response);
            } catch (Exception e) {
                e.printStackTrace();
                try {
                    response.getWriter().write("修改订单状态失败");
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                }
            }
        }
    }

    @RequestMapping("/createOrder")
    public void createOrder(HttpServletRequest request, HttpServletResponse response) {
        // 1.得到当前用户
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");
        // 2.从购物车中获取商品信息
        Map<Product, Integer> cart = (Map<Product, Integer>) session.getAttribute("cart");
        // 3.将数据封装到订单对象中
        Order order = new Order();
        try {
            BeanUtils.populate(order, request.getParameterMap());
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        order.setId(IdUtils.getUUID());// 封装订单id
        order.setUser(user);// 封装用户信息到订单.
        for (Product p : cart.keySet()) {
            OrderItem item = new OrderItem();
            item.setOrder(order);
            item.setBuynum(cart.get(p));
            item.setP(p);
            order.getOrderItems().add(item);
        }
        System.out.println(order);
        // 4.调用service中添加订单操作.
        orderService.addOrder(order);
        //		request.getRequestDispatcher("/client/orderlist.jsp").forward(request, response);
        try {
            response.sendRedirect(request.getContextPath() + "/client/createOrderSuccess.jsp");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("/delOrderById")
    public void delOrderById(HttpServletRequest request, HttpServletResponse response) {
        // 订单id
        String id = request.getParameter("id");
        // 已支付的订单带有type值为client的参数
        String type = request.getParameter("type");
        if (type != null && type.trim().length() > 0) {
            orderService.delOrderById(id);
            if ("admin".equals(type)) {
                try {
                    request.getRequestDispatcher("/findOrders").forward(request, response);
                } catch (ServletException | IOException e) {
                    e.printStackTrace();
                }
                return;
            }
        } else {
            // 调用service层方法删除相应订单
            orderService.delOrderByIdWithClient(id);
        }
        //response.sendRedirect(request.getContextPath() + "/client/delOrderSuccess.jsp");
        try {
            request.getRequestDispatcher("/findOrderByUser").forward(request, response);
        } catch (ServletException | IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("/findOrderById")
    public void findOrderById(HttpServletRequest request, HttpServletResponse response) {
        //1.获取用户类型
        String type = request.getParameter("type");
        //2.得到要查询的订单的id
        String id = request.getParameter("id");
        //3.根据id查找订单
        Order order = orderService.findOrderById(id);
        //4.将查询出的订单信息添加到request作用域中
        request.setAttribute("order", order);
        //5.如果用户类型不为null，则请求转发到view.jsp页面，否则转发到orderInfo.jsp页面
        if (type != null) {
            try {
                request.getRequestDispatcher("/admin/orders/view.jsp").forward(request, response);
            } catch (ServletException | IOException e) {
                e.printStackTrace();
            }
            return;
        }
        try {
            request.getRequestDispatcher("/client/orderInfo.jsp").forward(request, response);
        } catch (ServletException | IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("/findOrderByUser")
    public void findOrderByUserServlet(HttpServletRequest request, HttpServletResponse response) {
        // 获取名为“user”的session
        User user = (User) request.getSession().getAttribute("user");
        // 调用service中的方法,根据用户信息查找订单
        List<Order> orders = orderService.findOrderByUser(user);
        request.setAttribute("orders", orders);
        try {
            request.getRequestDispatcher("/client/orderlist.jsp").forward(request, response);
        } catch (ServletException | IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("/findProductById")
    public void findProductById(HttpServletRequest request, HttpServletResponse response) {
        // 得到商品的id
        String id = request.getParameter("id");
        // 获取type参数值，此处的type用于区别普通用户和超级用户
        String type = request.getParameter("type");
        try {
            // 调用service层方法，通过id查找商品
            Product p = productService.findProductById(id);
            request.setAttribute("p", p);
            // 普通用户默认不传递type值，会跳转到info.jsp页面
            if (type == null) {
                try {
                    request.getRequestDispatcher("/client/info.jsp").forward(request, response);
                } catch (ServletException | IOException e) {
                    e.printStackTrace();
                }
                return;
            }
            try {
                request.getRequestDispatcher("/admin/products/edit.jsp").forward(request, response);
            } catch (ServletException | IOException e) {
                e.printStackTrace();
            }
        } catch (FindProductByIdException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("/manager/AddNoticeServlet")
    public void addNotice(HttpServletRequest request, HttpServletResponse response) {
        Notice bean = new Notice();
        //获取表单参数
        String title = request.getParameter("title");
        String details = request.getParameter("details");

        //将当前时间设为添加公告的时间
        String t = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        bean.setTitle(title);
        bean.setDetails(details);
        bean.setN_time(t);
        //调用addNotice方法
        nService.addNotice(bean);

        try {
            request.getRequestDispatcher("/manager/ListNoticeServlet").forward(request, response);
        } catch (ServletException | IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("/manager/DeleteNoticeServlet")
    public void deleteNotice(HttpServletRequest request, HttpServletResponse response) {
        //获取请求参数，公告id
        String n_id = request.getParameter("id");

        //调用dao层方法
        nService.deleteNotice(n_id);

        try {
            request.getRequestDispatcher("/manager/ListNoticeServlet").forward(request, response);
        } catch (ServletException | IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("/deleteProduct")
    public void deleteProduct(HttpServletRequest request, HttpServletResponse response) {
        // 获取请求参数，产品id
        String id = request.getParameter("id");
        // 调用service完成添加商品操作
        productService.deleteProduct(id);
        try {
            response.sendRedirect(request.getContextPath() + "/listProduct");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("/manager/EditNoticeServlet")
    public void editNotice(HttpServletRequest req, HttpServletResponse resp) {
        Notice bean = new Notice();
        //获取表单参数
        int n_id = Integer.parseInt(req.getParameter("id"));
        String title = req.getParameter("title");
        String details = req.getParameter("details");

        //将当前时间设为添加公告的时间
        String t = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());

        bean.setN_id(n_id);
        bean.setTitle(title);
        bean.setDetails(details);
        bean.setN_time(t);

        //调用dao层方法
        nService.updateNotice(bean);

        try {
            req.getRequestDispatcher("/manager/ListNoticeServlet").forward(req, resp);
        } catch (ServletException | IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("/editProduct")
    public void editProduct(HttpServletRequest request, HttpServletResponse response) {
        Product p = new Product();
        Map<String, String> map = new HashMap<String, String>();
        String name = request.getParameter("name");
        String price = request.getParameter("price");
        String pnum = request.getParameter("pnum");
        String category = request.getParameter("category");
        String description = request.getParameter("description");
        String id = request.getParameter("id");
        p.setId(id);
        p.setDescription(description);
        p.setCategory(category);
        p.setName(name);
        p.setPnum(Integer.parseInt(pnum));
        p.setPrice(Double.parseDouble(price));
        DiskFileItemFactory dfif = new DiskFileItemFactory();
        // 设置临时文件存储位置
        dfif.setRepository(new File(request.getServletContext().getRealPath("/temp")));
        // 设置上传文件缓存大小为10m
        dfif.setSizeThreshold(1024 * 1024 * 10);
        // 创建上传组件
        ServletFileUpload upload = new ServletFileUpload(dfif);
        // 处理上传文件中文乱码
        upload.setHeaderEncoding("utf-8");
        try {
            // 解析request得到所有的FileItem
            List<FileItem> items = upload.parseRequest(request);
            // 遍历所有FileItem
            for (FileItem item : items) {
                // 判断当前是否是上传组件
                if (item.isFormField()) {
                    // 不是上传组件
                    String fieldName = item.getFieldName(); // 获取组件名称
                    String value = null; // 解决乱码问题
                    try {
                        value = item.getString("utf-8");
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                    map.put(fieldName, value);
                } else {
                    // 是上传组件
                    // 得到上传文件真实名称
                    String fileName = item.getName();
                    if (fileName != null && fileName.trim().length() > 0) {
                        fileName = FileUploadUtils.subFileName(fileName);

                        // 得到随机名称
                        String randomName = FileUploadUtils.generateRandonFileName(fileName);

                        // 得到随机目录
                        String randomDir = FileUploadUtils.generateRandomDir(randomName);
                        // 图片存储父目录
                        String imgurl_parent = "/productImg" + randomDir;

                        File parentDir = new File(request.getServletContext().getRealPath(imgurl_parent));
                        // 验证目录是否存在，如果不存在，创建出来
                        if (!parentDir.exists()) {
                            parentDir.mkdirs();
                        }

                        String imgurl = imgurl_parent + "/" + randomName;

                        map.put("imgurl", imgurl);

                        try {
                            IOUtils.copy(item.getInputStream(), new FileOutputStream(new File(parentDir, randomName)));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        item.delete();
                    }
                }

            }

        } catch (FileUploadException e) {
            e.printStackTrace();

        }

        try {
            // 将数据封装到javaBean中
            BeanUtils.populate(p, map);
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }


        // 调用service完成修改商品操作
        productService.editProduct(p);
        try {
            response.sendRedirect(request.getContextPath() + "/listProduct");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("/manager/FindByIdNoticeServlet")
    public void findByIdNoticeServlet(HttpServletRequest req, HttpServletResponse resp) {

        //获取公告id
        String n_id = req.getParameter("id");
        Notice notice = nService.findNoticeById(n_id);

        req.setAttribute("n", notice);

        try {
            req.getRequestDispatcher("/admin/notices/edit.jsp").forward(req, resp);
        } catch (ServletException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @RequestMapping("findOrderByManyCondition")
    public void findOrderByManyCondition(HttpServletRequest request, HttpServletResponse response) throws
            ServletException, IOException {
        String id = request.getParameter("id");
        String receiverName = request.getParameter("receiverName");
        //创建Service层对象

        //调用Service层OrderService类的findOrderByManyCondition()方法查询数据
        List<Order> orders = orderService.findOrderByManyCondition(id, receiverName);
        //将查询结果添加到request作用域中
        request.setAttribute("orders", orders);
        //请求转发到list.jsp页面，并将request请求和response响应也转发到该页面中
        try {
            request.getRequestDispatcher("/admin/orders/list.jsp").forward(request, response);
        } catch (ServletException | IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("findOrders")
    public void findOrders(HttpServletRequest request, HttpServletResponse response) {
        // 调用Service层对象的findAllOrder()方法查询订单列表
        List<Order> orders = orderService.findAllOrder();
        //将查询到的订单信息添加到request作用域
        request.setAttribute("orders", orders);
        // 将请求转发到list.jsp页面
        try {
            request.getRequestDispatcher("/admin/orders/list.jsp").forward(request, response);
        } catch (ServletException | IOException e) {
            e.printStackTrace();
        }
    }


    @RequestMapping("findProductByManyCondition")
    public void findProductByManyCondition(HttpServletRequest request, HttpServletResponse response) {
        //1.获取表单数据
        String id = request.getParameter("id"); // 商品id
        String name = request.getParameter("name"); // 商品名称
        String category = request.getParameter("category"); // 商品类别
        String minprice = request.getParameter("minprice"); // 最小价格
        String maxprice = request.getParameter("maxprice"); // 最大价格

        // 3.调用service层用于条件查询的方法
        List<Product> ps = productService.findProductByManyCondition(id, name, category, minprice, maxprice);
        // 4.将条件查询的结果放进request域中
        request.setAttribute("ps", ps);
        // 5.请求重定向到商品管理首页list.jsp页面
        try {
            request.getRequestDispatcher("/admin/products/list.jsp").forward(request, response);
        } catch (ServletException | IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("/manager/ListNoticeServlet")
    public void listNotice(HttpServletRequest req, HttpServletResponse resp) {
        List<Notice> notices = nService.getAllNotices();
        req.setAttribute("notices", notices);
        try {
            req.getRequestDispatcher("/admin/notices/list.jsp").forward(req, resp);
        } catch (ServletException | IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("listProduct")
    public void listProduct(HttpServletRequest request, HttpServletResponse response) {
        try {
            // 2.调用service层用于查询所有商品的方法
            List<Product> ps = productService.listAll();
            // 3.将查询出的所有商品放进request域中
            request.setAttribute("ps", ps);
            // 4.重定向到list.jsp页面
            request.getRequestDispatcher("/admin/products/list.jsp").forward(request, response);
            return;
        } catch (ListProductException e) {
            e.printStackTrace();
            try {
                response.getWriter().write(e.getMessage());
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        } catch (ServletException | IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("updateNoticeServlet")
    public void updateNotice(HttpServletRequest req, HttpServletResponse resp) {
        Notice bean = new Notice();
        //获取表单参数
        String title = req.getParameter("title");
        String details = req.getParameter("details");

        //将当前时间设为添加公告的时间
        String t = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        bean.setTitle(title);
        bean.setDetails(details);
        bean.setN_time(t);
        //调用dao层方法
        nService.addNotice(bean);

        try {
            req.getRequestDispatcher("/manager/ListNoticeServlet").forward(req, resp);
        } catch (ServletException | IOException e) {
            e.printStackTrace();
        }
    }
}
